package com.parking.bang.rpc.serialize.kryo;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

import com.esotericsoftware.kryo.pool.KryoPool;
import com.google.common.io.Closer;
import com.parking.bang.rpc.serialize.base.CodecUtil;

import io.netty.buffer.ByteBuf;

/**
 * CodecUtil Implements
 * 
 * @author ivan
 *
 */
public class KryoCodecUtil implements CodecUtil {

	private KryoPool pool;
	private static Closer closer = Closer.create();

	public KryoCodecUtil(KryoPool pool) {
		super();
		this.pool = pool;
	}

	/**
	 * Encode
	 */
	public void encode(ByteBuf out, Object message) throws IOException {
		try {
			ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
			closer.register(byteArrayOutputStream);
			KryoSerialize kryoSerialization = new KryoSerialize(pool);
			kryoSerialization.serialize(byteArrayOutputStream, message);
			byte[] body = byteArrayOutputStream.toByteArray();
			int dataLength = body.length;
			out.writeInt(dataLength);
			out.writeBytes(body);
		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			closer.close();
		}

	}

	/**
	 * Decode
	 */
	public Object decode(byte[] body) throws IOException {
		try {
			ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body);
			closer.register(byteArrayInputStream);
			KryoSerialize kryoSerialization = new KryoSerialize(pool);
			Object obj = kryoSerialization.deserialize(byteArrayInputStream);
			return obj;
		} catch (Exception ex) {
			ex.printStackTrace();
			return null;
		} finally {
			closer.close();
		}
	}

}
